package org.larkdoc.config;

import java.sql.SQLException;

import javax.sql.DataSource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;

/**
 * 阿里数据连接池配置
 * 
 * @author  zhangpeijun
 * @version  [v1.0.1, 2017年3月9日]
 * @see  [相关类/方法]
 * @since  [产品/模块版本]
 */
@Configuration
@ConfigurationProperties(prefix = "spring.datasource")
public class DruidConfig {
    
    private final static Logger LOG = LoggerFactory.getLogger(DruidConfig.class);
    
    private String              url;
    
    private String              username;
    
    private String              password;
    
    private String              driverClassName;
    
    private int                 initialSize;
    
    private int                 minIdle;
    
    private int                 maxActive;
    
    private int                 maxWait;
    
    private int                 timeBetweenEvictionRunsMillis;
    
    private int                 minEvictableIdleTimeMillis;
    
    private String              validationQuery;
    
    private boolean             testWhileIdle;
    
    private boolean             testOnBorrow;
    
    private boolean             testOnReturn;
    
    private boolean             poolPreparedStatements;
    
    private int                 maxPoolPreparedStatementPerConnectionSize;
    
    private String              filters;
    
    private String              connectionProperties;
    
    /**
     * 加载Bean
     * @return
     * 
     * @returns DataSource
     * @see [类、类#方法、类#成员]
     * @author  zhangpeijun[zhangpeijun1024@qq.com]<br/>
     *          2017年10月17日上午11:04:57
     */
    @Bean
    @Primary
    public DataSource dataSource() {
        // @Bean  声明其为Bean实例
        // @Primary 在同样的DataSource中，首先使用被标注的DataSource
        LOG.info("DataSource init start...");
        DruidDataSource datasource = new DruidDataSource();
        datasource.setUrl(this.url);
        datasource.setUsername(username);
        datasource.setPassword(password);
        datasource.setDriverClassName(driverClassName);
        // configuration
        datasource.setInitialSize(initialSize);
        datasource.setMinIdle(minIdle);
        datasource.setMaxActive(maxActive);
        datasource.setMaxWait(maxWait);
        datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
        datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
        datasource.setValidationQuery(validationQuery);
        datasource.setTestWhileIdle(testWhileIdle);
        datasource.setTestOnBorrow(testOnBorrow);
        datasource.setTestOnReturn(testOnReturn);
        datasource.setPoolPreparedStatements(poolPreparedStatements);
        datasource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);
        try {
            datasource.setFilters(filters);
        } catch (SQLException e) {
            LOG.error("DataSource init exception : ", e);
        }
        datasource.setConnectionProperties(connectionProperties);
        LOG.info("DataSource init end...");
        return datasource;
    }
    
    /**
     * 设置durid过滤器
     * @return [参数说明]
     * 
     * @return FilterRegistrationBean [返回类型说明]
     * @exception throws [违例类型] [违例说明]
     * @see [类、类#方法、类#成员]
     */
    @Bean
    public FilterRegistrationBean filterRegistrationBean() {
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
        filterRegistrationBean.setFilter(new WebStatFilter());
        filterRegistrationBean.addUrlPatterns("/*");
        filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
        filterRegistrationBean.addInitParameter("profileEnable", "true");
        filterRegistrationBean.addInitParameter("principalCookieName", "USER_COOKIE");
        filterRegistrationBean.addInitParameter("principalSessionName", "USER_SESSION");
        return filterRegistrationBean;
    }
    
    /**
     * 设置durid监控配置
     * 
     * @return ServletRegistrationBean [返回类型说明]
     * @exception throws [违例类型] [违例说明]
     * @see [类、类#方法、类#成员]
     */
    @Bean
    public ServletRegistrationBean druidServlet() {
        ServletRegistrationBean reg = new ServletRegistrationBean();
        reg.setServlet(new StatViewServlet());
        reg.addUrlMappings("/druid/*");
        reg.addInitParameter("loginUsername", "lost");
        reg.addInitParameter("loginPassword", "lost123");
        return reg;
    }
    
    public String getUrl() {
        return url;
    }
    
    public void setUrl(String url) {
        this.url = url;
    }
    
    public String getUsername() {
        return username;
    }
    
    public void setUsername(String username) {
        this.username = username;
    }
    
    public String getPassword() {
        return password;
    }
    
    public void setPassword(String password) {
        this.password = password;
    }
    
    public String getDriverClassName() {
        return driverClassName;
    }
    
    public void setDriverClassName(String driverClassName) {
        this.driverClassName = driverClassName;
    }
    
    public int getInitialSize() {
        return initialSize;
    }
    
    public void setInitialSize(int initialSize) {
        this.initialSize = initialSize;
    }
    
    public int getMinIdle() {
        return minIdle;
    }
    
    public void setMinIdle(int minIdle) {
        this.minIdle = minIdle;
    }
    
    public int getMaxActive() {
        return maxActive;
    }
    
    public void setMaxActive(int maxActive) {
        this.maxActive = maxActive;
    }
    
    public int getMaxWait() {
        return maxWait;
    }
    
    public void setMaxWait(int maxWait) {
        this.maxWait = maxWait;
    }
    
    public int getTimeBetweenEvictionRunsMillis() {
        return timeBetweenEvictionRunsMillis;
    }
    
    public void setTimeBetweenEvictionRunsMillis(int timeBetweenEvictionRunsMillis) {
        this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
    }
    
    public int getMinEvictableIdleTimeMillis() {
        return minEvictableIdleTimeMillis;
    }
    
    public void setMinEvictableIdleTimeMillis(int minEvictableIdleTimeMillis) {
        this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
    }
    
    public String getValidationQuery() {
        return validationQuery;
    }
    
    public void setValidationQuery(String validationQuery) {
        this.validationQuery = validationQuery;
    }
    
    public boolean isTestWhileIdle() {
        return testWhileIdle;
    }
    
    public void setTestWhileIdle(boolean testWhileIdle) {
        this.testWhileIdle = testWhileIdle;
    }
    
    public boolean isTestOnBorrow() {
        return testOnBorrow;
    }
    
    public void setTestOnBorrow(boolean testOnBorrow) {
        this.testOnBorrow = testOnBorrow;
    }
    
    public boolean isTestOnReturn() {
        return testOnReturn;
    }
    
    public void setTestOnReturn(boolean testOnReturn) {
        this.testOnReturn = testOnReturn;
    }
    
    public boolean isPoolPreparedStatements() {
        return poolPreparedStatements;
    }
    
    public void setPoolPreparedStatements(boolean poolPreparedStatements) {
        this.poolPreparedStatements = poolPreparedStatements;
    }
    
    public int getMaxPoolPreparedStatementPerConnectionSize() {
        return maxPoolPreparedStatementPerConnectionSize;
    }
    
    public void setMaxPoolPreparedStatementPerConnectionSize(int maxPoolPreparedStatementPerConnectionSize) {
        this.maxPoolPreparedStatementPerConnectionSize = maxPoolPreparedStatementPerConnectionSize;
    }
    
    public String getFilters() {
        return filters;
    }
    
    public void setFilters(String filters) {
        this.filters = filters;
    }
    
    public String getConnectionProperties() {
        return connectionProperties;
    }
    
    public void setConnectionProperties(String connectionProperties) {
        this.connectionProperties = connectionProperties;
    }
    
}
